﻿
//2014.1.31
//调整了分配地址和生成代码的位置, 先全部分配所有芯片的变量地址, 再进行代码转换,
//可能导致MCS51等不可重入芯片类型无法正常编译运行
//把以前的分配函数复制了一个备份文件.

//分配地址
namespace n_Malloc
{
using System;
using System.Text;
using n_AddressList;
using n_CodeData;
using n_Config;
using n_ConstString;
using n_CPUType;
using n_ET;
using n_FunctionCodeList;
using n_FunctionList;
using n_MemberType;
using n_SuperASM;
using n_VarList;
using n_VarType;
using n_VdataList;
using n_CallList;

public static class MallocAvr
{
	//分配全部地址
	public static string[] ApplyAddress()
	{
		//重置地址集合
		AddressList.Reset();
		
		//重置所有变量的存在属性
		VarList.ResetAllVar();
		
		CodeData.Reset( Config.ChipNumber );
		
		string[] ChipList = new string[ Config.ChipNumber ];
		
		//分配静态变量地址
		for( int i = 0; i < Config.ChipNumber; ++i ) {
			Config.SetChipIndex( i );
			Malloc.ApplyStaticAddress( i );
		}
		//分配局部变量地址, 转换代码
		for( int i = 0; i < Config.ChipNumber; ++i ) {
			Config.SetChipIndex( i );
			
			SetFuncIntFlag( i );
			
			SwitchOnceChipCode( i );
			
			ChipList[ i ] = Malloc.Result.ToString();
		}
		return ChipList;
	}
	
	//分配全部地址
	static void SwitchOnceChipCode( int ChipIndex )
	{
		Malloc.Result = new StringBuilder( "" );
		string[] Function = Malloc.GetFunctionArray( ChipIndex );
		
		for( int i = 0; i < Function.Length; ++i ) {
			if( Function[ i ] != null ) {
				
				if( !n_FunctionList.FunctionList.Get( i ).isUsed &&
				    n_FunctionList.FunctionList.Get( i ).InterType != MemberType.FunctionType.Interrupt &&
				    i != Config.GetStartFunction() ) {
				   	//n_OS.VIO.Show( n_FunctionList.FunctionList.Get( i ).FunctionName );
					continue;
				}
				//清空地址列表
				AddressList.Clear();
				VdataList.Get( VdataList.GetIndex( VarType.VBase ) ).StartAddress = 0;
				SuperASM.Run( i, Function[ i ] );
			}
		}
	}
	
	//处理全部的中断函数标志
	static void SetFuncIntFlag( int ChipIndex )
	{
		for( int i = 0; i < FunctionList.length; ++i ) {
			FunctionList.Get( i ).Dealed = false;
		}
		for( int i = 0; i < FunctionList.length; ++i ) {
			if( FunctionList.Get( i ).InterType == MemberType.FunctionType.Interrupt ) {
				FunctionList.Get( i ).isInter = true;
				SetSubInt( i );
			}
		}
	}
	
	//设置当前函数的使用标志及调用函数列表使用标志
	static void SetSubInt( int FuncIndex )
	{
		if( FunctionList.Get( FuncIndex ).Dealed ) {
			return;
		}
		FunctionList.Get( FuncIndex ).Dealed = true;
		
		string s = n_CallList.CallList.GetSubFunction( FuncIndex ).Trim( ' ' );
		
		if( s != "" ) {
			string[] SubList = s.Split( ' ' );
			for( int i = 0; i < SubList.Length; ++i ) {
				int subi = int.Parse( SubList[i] );
				FunctionList.Get( subi ).isInter = true;
				SetSubInt( subi );
			}
		}
	}
}

public static class MallocMcs51
{
	//分配全部地址
	public static string[] ApplyAddress()
	{
		//重置地址集合
		AddressList.Reset();
		
		//重置所有变量的存在属性
		VarList.ResetAllVar();
		
		CodeData.Reset( Config.ChipNumber );
		
		string[] ChipList = new string[ Config.ChipNumber ];
		for( int i = 0; i < ChipList.Length; ++i ) {
			Config.SetChipIndex( i );
			ChipList[ i ] = ApplyOnceAddress( i );
		}
		return ChipList;
	}
	
	//分配全部地址
	static string ApplyOnceAddress( int ChipIndex )
	{
		//分配静态地址
		Malloc.ApplyStaticAddress( ChipIndex );
		
		n_Malloc.Malloc.Result = new StringBuilder( "" );
		string[] Function = Malloc.GetFunctionArray( ChipIndex );
		MalocedIntFunction = "";
		
		//初始化--所有函数都未分配地址
		isMalloc = new bool[ FunctionList.length ];
		for( int i = 0; i < isMalloc.Length; ++i ) {
			if( FunctionList.Get( i ).InterType == MemberType.FunctionType.Interface && Config.GetCPU() == CPUType.PC80X86 ) {
				isMalloc[ i ] = true;
			}
			else {
				isMalloc[ i ] = false;
			}
		}
		//分配所有的进程函数
		for( int i = 0; i < Function.Length; ++i ) {
			if( FunctionList.Get( i ).InterType != MemberType.FunctionType.Interrupt &&
				FunctionList.Get( i ).InterType != MemberType.FunctionType.Task ) {
				continue;
			}
			if( Function[ i ] == null ) {
				continue;
			}
			//先分配子函数
			string call = CallList.GetSubFunction( i ).Trim( ' ' );
			if( call != "" ) {
				string[] Cut = call.Split( ' ' );
				do {
					NotComplete = false;
					for( int j = 0; j < Cut.Length; ++j ) {
						int FuncIndex = int.Parse( Cut[ j ] );
						if( !isMalloc[ FuncIndex ] ) {
							MallocFunction( Function, FuncIndex, ChipIndex );
						}
					}
				}
				while( NotComplete );
			}
			//再分配当前函数
			MallocFunction( Function, i, ChipIndex );
			MalocedIntFunction += i + " ";
		}
		
		int BaseVdataIndex = VdataList.GetIndex( VarType.VBase );
		n_Interrupt.Interrupt.StartAddrOfBaseCode = AddressList.StaticMaxAddr[ BaseVdataIndex ] + 1;
		
		//分配非进程函数
		do {
			NotComplete = false;
			for( int i = 0; i < Function.Length; ++i ) {
				if( !isMalloc[ i ] && Function[ i ] != null ) {
					MallocFunction( Function, i, ChipIndex );
				}
			}
		}
		while( NotComplete );
		
		//检查是否有未分配的函数
		for( int i = 0; i < FunctionList.length; ++i ) {
			if( !isMalloc[ i ] && Function[ i ] != null ) {
				ET.WriteParseError( 0, "函数中存在递归调用----函数名: " + FunctionList.Get( i ).FunctionName );
			}
		}
		return n_Malloc.Malloc.Result.ToString();
	}
	
	//分配单个函数变量地址
	static void MallocFunction( string[] Function, int FuncIndex, int ChipIndex )
	{
		string s = CallList.GetSubFunction( FuncIndex ).Trim( ' ' );
		if( s != "" ) {
			string[] SubFunction = s.Split( ' ' );
			for( int i = 0; i < SubFunction.Length; ++i ) {
				int SubIndex = int.Parse( SubFunction[ i ] );
				if( !isMalloc[ SubIndex ] ) {
					return;
				}
			}
		}
		//清空地址列表
		AddressList.Clear();
		
		if( !Config.isReentrant() ) {
			//重置静态变量地址
			ResetStaticVar( ChipIndex );
			//重置子函数地址
			ResetSubFunction( FuncIndex );
			//重置中断函数地址
			if( MalocedIntFunction != "" ) {
				string[] Cut = MalocedIntFunction.TrimEnd( ' ' ).Split( ' ' );
				for( int i = 0; i < Cut.Length; ++i ) {
					int index = int.Parse( Cut[ i ] );
					ResetFunction( index );
				}
			}
		}
		else {
			VdataList.Get( VdataList.GetIndex( VarType.VBase ) ).StartAddress = 0;
		}
		SuperASM.Run( FuncIndex, Function[ FuncIndex ] );
		isMalloc[ FuncIndex ] = true;
		NotComplete = true;
	}
	
	//重置所有静态变量的变量地址
	static void ResetStaticVar( int ChipIndex )
	{
		for( int i = 0; i < VarList.length; ++i ) {
			if( VarList.Get( i ).ActiveType != "static" || VarList.Get( i ).ChipIndex != ChipIndex ) {
				continue;
			}
			if( VarList.Get( i ).IsOut ) {
				continue;
			}
			string Type = VarList.Get( i ).Type;
			string VdataName = VarType.GetStoreType( Type );
			int VdataIndex = VdataList.GetIndex( VdataName );
			if( VdataIndex == -1 ) {
				ET.WriteParseError( VarList.Get( i ).Location, "重置静态变量地址时发现未定义的虚拟数据类型:" + VdataName );
				continue;
			}
			if( !VdataList.Get( VdataIndex ).AutoAllot ) {
			   continue;
			}
			int Addr = int.Parse( VarList.GetAddr( i ) );
			int Width = VarType.GetSize( Type );
			int Start = VdataList.Get( VdataIndex ).StartAddress;
			int End = VdataList.Get( VdataIndex ).EndAddress;
			while( Width != 0 ) {
				AddressList.Address[ VdataIndex ][ Addr - Start + Width - 1 ] = true;
				--Width;
			}
		}
	}
	
	//重置所有子函数的变量地址
	static void ResetSubFunction( int FuncIndex )
	{
		string s = CallList.GetSubFunction( FuncIndex ).Trim( ' ' );
		if( s == "" ) {
			return;
		}
		string[] SubFunction = s.Split( ' ' );
		for( int i = 0; i < SubFunction.Length; ++i ) {
			int SubIndex = int.Parse( SubFunction[ i ] );
			for( int j = 0; j < VdataList.length; ++j ) {
				AddressList.UsedAddressList[ j ][ FuncIndex ] +=
					AddressList.UsedAddressList[ j ][ SubIndex ];
				}
		}
		for( int j = 0; j < VdataList.length; ++j ) {
			string ss = AddressList.UsedAddressList[ j ][ FuncIndex ].Trim( ' ' );
			if( ss == "" ) {
				continue;
			}
			string[] Cut = ss.Split( ' ' );
			for( int Addr = 0; Addr < Cut.Length; ++Addr ) {
				int a = int.Parse( Cut[ Addr ] );
				a -= VdataList.Get( j ).StartAddress;
				AddressList.Address[ j ][ a ] = true;
			}
		}
	}
	
	//重置一个函数的变量地址
	static void ResetFunction( int FuncIndex )
	{
		for( int j = 0; j < VdataList.length; ++j ) {
			string ss = AddressList.UsedAddressList[ j ][ FuncIndex ].Trim( ' ' );
			if( ss == "" ) {
				continue;
			}
			string[] Cut = ss.Split( ' ' );
			for( int Addr = 0; Addr < Cut.Length; ++Addr ) {
				int a = int.Parse( Cut[ Addr ] );
				a -= VdataList.Get( j ).StartAddress;
				AddressList.Address[ j ][ a ] = true;
			}
		}
	}
	
	static bool[] isMalloc;
	static bool NotComplete;
	static string MalocedIntFunction;
}

public static class Malloc
{
	//分配静态地址
	public static void ApplyStaticAddress( int ChipIndex )
	{
		for( int i = 0; i < VarList.length; ++i ) {
			
			//不是静态类型,跳过
			if( VarList.Get( i ).ActiveType != "static" ||
			    VarList.Get( i ).RealRefType == MemberType.RealRefType.link ||
			    VarList.Get( i ).ChipIndex != ChipIndex ) {
				continue;
			}
			//系统自动生成的变量 (switch标号地址数组和常量数组), 如果母函数被优化, 则不为此变量分配空间
			int findex = VarList.Get( i ).FunctionIndex;
			if( findex != -1 ) {
				if( !FunctionList.Get( findex ).isUsed ) {
					continue;
				}
			}
			string Address = VarList.GetAddr( i );
			
			//普通静态变量,分配地址
			if( Address == null ) {
				int Addr = AddressList.ApplyVarAddress( VarList.Get( i ).Type );
				VarList.Get( i ).Address = (Addr).ToString();
				
				//更新最大地址
				string VdataType = VarType.GetStoreType( VarList.Get( i ).Type );
				int VdataIndex = VdataList.GetIndex( VdataType );
				if( VdataIndex == -1 ) {
					ET.WriteParseError( VarList.Get( i ).Location, "分配静态变量地址时发现未定义的虚拟数据类型:" + VdataType );
					continue;
				}
				int Length = VarType.GetSize( VarList.Get( i ).Type );
				AddressList.RefreshMaxStaticUsedAddress( VdataIndex, Addr + Length - 1 );
				continue;
			}
			//已定义地址的静态变量,跳过
			if( !Address.StartsWith( "@code " ) ) {
				
				//注意!!! 这里还包括 &link 等类型
				
				continue;
			}
			string type = VarList.Get( i ).Type;
			int ErrorIndex = VarList.Get( i ).Location;
			
			//判断存储类型是否为 code 类型
			if( !VarType.StoreTypeisVcode( type ) ) {
				ET.WriteParseError( ErrorIndex, "数组常量只能放在ROM存储区中: " +
					VarType.GetStoreType( type ) );
				continue;
			}
			int AddressNumber = AddressList.ApplyVarAddress( type );
			VarList.Get( i ).Address = AddressNumber.ToString();
			
			//如果是atmega8芯片需要把长度限制为偶数个
			string CPUtype = Config.GetCPU();
			string basetype = type.Remove( 0, type.LastIndexOf( ' ' ) + 1 );
			Address = Address.Split( ' ' )[ 1 ];
			int DefineLength = VarType.GetSize( type );
			if( ( CPUtype.StartsWith( CPUType.MEGA_X ) ) &&
			    DefineLength % 2 != 0 &&
				( basetype == VarType.BaseType.Uint8 || basetype == VarType.BaseType.Sint8 ||
			      basetype == VarType.BaseType.Bool || basetype == VarType.BaseType.Bit ) ) {
				
				Address += ",0";
				string DataType = VarType.CreatVdataType( VarType.VCode, VarType.BaseType.Sint8 );
				AddressList.ApplyVarAddress( DataType );
			}
			
			//这里把有符号数转换为无符号数
			string[] Cut = Address.Split( ',' );
			Address = "";
			for( int n = 0; n < Cut.Length; ++n ) {
				
				string ArrayResult = null;
				
				if( Cut[ n ].StartsWith( "#" ) ) {
					
					
					//bool w0 = false;
					string Name = Cut[ n ].Remove( 0, 1 );
					if( Cut[ n ].StartsWith( "#addrw0+" ) ) {
						Name = Cut[ n ].Remove( 0, 8 );
						//w0 = true;
					}
					
					int j = VarList.GetStaticIndex( Name );
					if( j == -1 ) {
						
						//判断是否为函数
						j = FunctionList.GetIndex( Name );
						if( j == -1 ) {
							
							//这里允许label出现
							//ET.WriteParseError( ErrorIndex, "<Malloc>扫描数组常量时遇到未定义的静态变量(地址)或者函数地址: " + Name );
							//continue;
							
						}
						else {
							FunctionList.Get( j ).isUsed = true;
							n_Opti.Opti.SetSubUsed( j );
						}
					}
					ArrayResult = Cut[ n ];
				}
				else {
					ArrayResult = ConstExpression.GetRealValue( Cut[ n ], basetype );
				}
				if( ArrayResult == null ) {
					ET.WriteParseError( ErrorIndex, "常量超出范围: " + Cut[ n ] );
					ArrayResult = "0";
				}
				Address += ArrayResult;
				if( n != Cut.Length - 1 ) {
					Address += ',';
				}
			}
			CodeData.Add( basetype + " " + Address );
		}
	}
	
	//把中间语言指令序列分割为函数组
	public static string[] GetFunctionArray( int ChipIndex )
	{
		string[] Cut = new string[ FunctionList.length ];
		for( int i = 0; i < FunctionList.length; ++i ) {
			if( FunctionList.Get( i ).ChipIndex == ChipIndex || FunctionList.Get( i ).ChipIndex == -1 ) {
				Cut[ i ] = FunctionCodeList.GetCode( i );
			}
			else {
				Cut[ i ] = null;
			}
		}
		return Cut;
	}
	
	public static StringBuilder Result;
}
}



